package com.lin.missyou.core;

import com.lin.missyou.core.configuration.ExceptionCodeConfiguration;
import com.lin.missyou.exception.http.HttpException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolationException;
import java.util.List;

/**
 * 全局异常处理器
 *  抛出的异常最终都会在这里捕获
 * @author gcq
 * @Create 2021-10-04
 */
@RestControllerAdvice
public class GlobalExceptionAdivce {
    @Autowired
    private ExceptionCodeConfiguration exceptionCodeConfiguration;

    /**
     * ExceptionHandler 指定要拦截什么异常
     * ResponseStatus 返回的状态码
     * @param res
     * @param e
     * @return
     */
    @ExceptionHandler(value = Exception.class)
    @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
    public UnifyResponse handleException(HttpServletRequest res, Exception e){
        System.out.println("异常信息" + e);
        UnifyResponse unifyResponse = new UnifyResponse(9999, "服务期内部错误",
                res.getMethod() + " " + res.getRequestURI());
        return unifyResponse;
    }

    @ExceptionHandler(value = HttpException.class)
    public ResponseEntity handelHttpException(HttpServletRequest res, HttpException e){
        UnifyResponse message = new UnifyResponse(e.getCode(), exceptionCodeConfiguration.getMessage(e.getCode()),
                res.getMethod() + " " + res.getRequestURI());
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpStatus httpStatus = HttpStatus.resolve(e.getHttpStatusCode());

        ResponseEntity<UnifyResponse> r = new ResponseEntity<>(message, headers, httpStatus);
        return r;
    }

    /**
     * 违反约束
     * @param res
     * @param e
     * @return
     */
    @ExceptionHandler(ConstraintViolationException.class)
    @ResponseStatus(value = HttpStatus.BAD_REQUEST)
    public UnifyResponse handleConstrainException(HttpServletRequest res, ConstraintViolationException e){
        return new UnifyResponse(10001, e.getMessage(),
                res.getMethod() + " " + res.getRequestURI());
    }

    /**
     * 参数异常 验证未通过
     * @param res
     * @param e
     * @return
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseStatus(value = HttpStatus.BAD_REQUEST)
    public UnifyResponse handleBeanValidation(HttpServletRequest res, MethodArgumentNotValidException e){
        return new UnifyResponse(10001,
                formatAllErrorMessages(e.getBindingResult().getAllErrors()),
                res.getMethod() + " " + res.getRequestURI());
    }

    private String formatAllErrorMessages(List<ObjectError> errors){
        StringBuffer errorMsg = new StringBuffer();
        errors.forEach(i ->{
            errorMsg.append(i.getDefaultMessage()).append(";");
        });
        return errorMsg.toString();
    }
}